1. 简介

<script src="http://the5fireblog.b0.upaiyun.com/staticfile/jquery-1.10.2.js"></script>
<script src="http://the5fireblog.b0.upaiyun.com/staticfile/underscore.js"></script>
<script src="http://the5fireblog.b0.upaiyun.com/staticfile/backbone.js"></script>
  • Model是根据现实数据建立的抽象,比如人(People)

    Models可以创建并存储数据,进行数据验证,销毁或者保存到服务器上。

    当界面上的操作引起model中属性的变化时,model会触发change的事件。那些用来显示model状态的views会接受到model触发change的消息,进而发出对应的响应,并且重新渲染新的数据到界面。

  • Collection是Model的一个集合,比如一群人

  • View是对Model和Collection中数据的展示,把数据渲染(Render)到页面上

  • Router是对路由的处理,就像传统网站通过url现实不同的页面,在单页面应用(SPA)中通过Router来控制前面说的View的展示

2. Model

2.1 定义

var NewModel = Backbone.Model.extend({
  default: {
    author: 'nobody',
    title: 'null',
    description: 'nothing'
  },
  initialize: function(){
    // 一些和数据相关的事件绑定、监听事件等
  }
  urlRoot: '......./get/json'
});
  • 定义时可以什么属性都不要,没有强制属性
  • default:为实例化的每个对象添加默认值
  • initialize:在每个对象实例化时触发,建议放一些监听函数,见2.4
  • urlRoot:仅在有REST Server 的情况下使用,配合基本操作中的注释

2.2 实例

var obj = {
  author: 'Ethan',
  title: 'backbone model',
  description: "this is a description"
}
var newModel = new NewModel(obj);

2.3 基本操作

  • get an attribute

    newModel.get('author') ==> ‘Ethan’

  • set an attribute

    newModel.set({title: 'changed model title'})

  • get from server

    //实例化一个没有数据的model
    var anotherModel = new NewModel();		//也可以在定义时,增加一个urlRoot属性
    										//这样就实例为: var model = new Model({name: 'Ethan'});
    										//然后直接 model.fetch() 获取数据
    //指向获取json数据的地址
    anotherModel.url = '......./get/json'; 	
    
    //将获取到的json数据作为实例的数据
    anotherModel.fetch();	
    
  • sync / save modification to sever

    newModel.save()

    实际上进行了一个 put or post get/json/ethan with JSON params 的操作

  • others

    newModel.destroy();

    newModel.toJSON();

2.4 Event

model 的事件绑定和监听可以在Class 上,可也以在每一个实例上。下例针对一个实例进行绑定,若要在Class 上绑定,一般在定义 Model 的时候放在 initialize 里,见2.1

//绑定一个事件
newModel.on('event-name', function(){
  alert('event-name happened');
});
//触发一个事件
newModel.trigger('event-name');

事件名称可以是backbone (or jQuery) 预先定义的,如change 等,也可以是自定义事件,由trigger函数手动触发

下例是一个常见的监听操作,用来说明model事件的基本操作

newModel.on('change', doThings);	//绑定一个 doThings 函数
  • 通过修改model 触发

    newModel.set({title: "new title"});
    
  • 修改model 不触发绑定事件

    newModel.set({title: "new title"}, {silent: true});
    

alt

// TODO: 对象验证

3.Collection

3.1 定义

var NewCollection = new Backbone.Collection.extend({
  model: NewModel
});

3.2 实例

3.3 基本操作

  • the number of model instances

    newCollection.length;
    
  • add a model instance

    newCollection.add(newModel1);
    
  • get model instance at index

    newCollection.at(0);	//  ===>  newModel1
    
  • remove model instance

    newCollection.remove(newModel1); 
    
  • async with server

    // basic is same as model, not mentioned here
    // if the data returned from server is a long JSON, like
    // var data = [{a:a}, {b:b}, {c:c}]
    newCollection.reset(data) 	// ====> 变成三个model
    

3.4 Event

same as model

  • build-in event: add, remove, reset

  • 遍历collection

    newCollection.forEach(function(model){...})
    
  • map 也可以遍历,但是可以在回调里返回值,构造成一个array

  • filter 方法return 筛选过的结果

  • … 所有underscore 提供的数据集合方法这里都适用

TODO

4.View

在backbone 框架中,view负责所有的界面交互

4.1 定义

var NewView = Backbone.View.extend({
  initialize: function(){
    //一些监听方法,如 this.model.on('change',this.render, this);
  }
  tagname: 'p',
  id: 'viewId',
  className: 'viewClass',
  events: {"click h3": "alertStatus"},
  alertStatus: function(){...},
  render: function(){
    var html = '<h3>' + this.model.get('name') + '</h3>';
    this.$el.html(html);
  }
});
  • 定义时可以什么属性都不要,没有强制属性,但是建议要有render方法去渲染view

  • initialize 会在实例化每个对象时添加,建议把针对数据 Model 的监听事件放进这里

    这里用了 this.model.on('change',this.render, this); ,其中第三个参数,表示第二个参数 this.render 里的 this具体指向谁,如果没有第三个参数,有些情况下 this 会指向 window

  • tagName: 不写默认是 ‘div’

  • events 和 具体函数参见 4.4

  • 这里调用了 this.model.get 方法,其实model 里的任何 (包括自定义的) 方法都可以由view 来调用

4.2 实例

var newView = new NewView( {model: newModel} );
newView.render(); 	//====> create <p id='viewId' class='viewClass'><h3>张三</h3></p>

4.3 Template

var TemplateView = Backbone.View.extend({
  
  var template = _.template("<h3><%= description %></h3>");
  
  render: function() {
  	var attribute = this.model.toJSON();
  	this.$el.html(template(attribute));
  }
});

var templateView = new TemplateView({ model: newModel });
templateView.render();
  • 除此之外,也可以在HTML中利用 <script type="text/template">...</script> 定义模版 在构造 TemplateView 时,也应该用: var template = _.template($("#HTML_template").html());

4.4 Event

views are responsible for responding to all user interactions via events.

var AnotherView = Backbone.View.Extend({
  events: {
    "dbclick"		:	"open",
    'click .a .b'	:	"close",
    'mouseover #c'	:	"toggle",
    "click h3"		:	"alertStatus",
    ...
  },
  
  alertStatus: function(e){
    alert("you clicked h3 tag");
  }  
})
  • 没有加对象的,表示该view 上的所有对象,比如第一个dbclick

Router

单页应用中,浏览器的url始终要定位到当前页面,通过hash(#page)的方式来完成。但现在可以通过history API来完成,可以直接使用 /page 来完成之前需要hash来完成的操作。

  1. 例子

    <a href="#actions">testActions</a>
    <a href="#/posts/120">Post 120</a>
    
    var AppRouter = Backbone.Router.extend({
        routes: {
            "posts/:id" : "getPost",
            "*actions" : "defaultRoute"
        },
    
        defaultRoute : function(actions){		//点击testActions触发该方法
            alert(actions);
        },
      
        getPost: function(id) {			//点击Post 120 触发该方法,并把120作为参数传进来
            alert(id);
        }
    });
    
    var app_router = new AppRouter;
    
    Backbone.history.start();